<?php

namespace app\common\controller;

use alipay\aop\AopClient;
use alipay\aop\request\AlipayTradePagePayRequest;
use alipay\aop\request\AlipayTradeWapPayRequest;
use app\common\model\RechargeModel;

class AlipayController
{
    private $config;

    public function __construct()
    {
        $this->config = config('app.alipay');
    }

    /**
     *生成APP支付订单信息
     * @param string $orderId 商品订单ID
     * @param string $subject 支付商品的标题
     * @param string $body 支付商品描述
     * @param float $pre_price 商品总支付金额
     * @param int $expire 支付交易时间
     * @return bool|string 返回支付宝签名后订单信息，否则返回false
     */
    public function unifiedorder($order_id, $name, $price)
    {
        try {
            $aop = new AopClient();
            $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
            $aop->appId = $this->config['app_id'];
            $aop->rsaPrivateKey = $this->config['private_key'];
            $aop->format = "json";
            $aop->charset = "UTF-8";
            $aop->signType = "RSA2";
            $aop->alipayrsaPublicKey = $this->config['ali_public_key'];
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            $request = new AlipayTradePagePayRequest();
            // $request = new AlipayTradeWapPayRequest();
            //SDK已经封装掉了公共参数，这里只需要传入业务参数
            $content = [
                'body' => $name,
                'subject' => $name,
                'out_trade_no' => $order_id,
                'timeout_express' => '1d',
                'total_amount' => $price,
                'product_code' => 'FAST_INSTANT_TRADE_PAY',
                // 'product_code' => 'QUICK_WAP_WAY',
            ];
            $bizcontent = json_encode($content, JSON_UNESCAPED_UNICODE);
            // cmf_log(date('Y-m-d H:i:s') . '<br>支付信息：' . PHP_EOL . $bizcontent, './alipay.log');
            $request->setNotifyUrl($this->config['notify_url']);
            $request->setReturnUrl($this->config['return_url']);
            $request->setBizContent($bizcontent);
            //这里和普通的接口调用不同，使用的是sdkExecute
//            $response = $aop->sdkExecute($request);
            $response = $aop->pageExecute($request);
            //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义，实际打印到日志以及http传输不会有这个问题
            return $response;
//            return htmlspecialchars($response);//就是orderString 可以直接给客户端请求，无需再做处理。
        } catch (\Exception $e) {
            return $e->getMessage();
        }

    }

    public function notify()
    {
        $fp = fopen('./alipay_notify.log', 'a+');//log/201904/29ali_notify.txt
        fwrite($fp, date("Y-m-d H:i:s") . "\r\n");
        fwrite($fp, var_export($_POST, true) . "\r\n");
        //验证签名

        $aop = new AopClient();
        $aop->alipayrsaPublicKey = $this->config['ali_public_key'];
        $flag = $aop->rsaCheckV1($_POST, NULL, "RSA2");

        //验签
        if ($flag) {
            //处理业务，并从$_POST中提取需要的参数内容
            if ($_POST['trade_status'] == 'TRADE_SUCCESS' || $_POST['trade_status'] == 'TRADE_FINISHED') {//处理交易完成或者支付成功的通知
                //获取订单号
                $orderId = $_POST['out_trade_no'];
                //交易号
                $trade_no = $_POST['trade_no'];

                $res = RechargeModel::pay_notify($_POST);
                if (!$res) {
                    fwrite($fp, "错误信息：" . RechargeModel::getErrorInfo() . date("Y-m-d H:i:s") . "\r\n");
                    die('fail');
                } else {
                    fwrite($fp, "支付成功：" . date("Y-m-d H:i:s") . "\r\n");
                    die('success');
                }

                //处理成功一定要返回 success 这7个字符组成的字符串，
                //die('success');//响应success表示业务处理成功，告知支付宝无需在异步通知

            } else {
                fwrite($fp, "错误信息：" . $_POST['trade_status'] . date("Y-m-d H:i:s") . "\r\n");
                die('fail');
            }
        } else {
            fwrite($fp, "错误信息：签名验证失败" . date("Y-m-d H:i:s") . "\r\n");
            die('fail');
        }

    }
}